<template>
	<scroll-view scroll-y class="group" :style="{ '--fss': app.theme.fss() }">
		<movable-area
			class="drag-sort"
			id="drag"
			:style="{ height: currentListLength + 'px' }"
			@touchstart="isPreventDefault"
			@touchmove="isPreventDefault"
			@touchend="isPreventDefault"
		>
			<movable-view
				v-for="(item, index) in currentList"
				:key="index"
				:x="0"
				:y="item.y"
				direction="vertical"
				disabled
				damping="40"
				class="drag-sort-item"
				:style="{ 'height': height + 'px' }" 
				:animation="active !== index"
				:class="{ 
					'item_active': active === index, 
					'item_after': item.index > 0 
				}"
			>
				<view class="item flex">
					<view class="imageView flex">
						<image :src="item.cover" mode="aspectFill" class="image"></image>
						<view class="flex" load v-if="item.playStatus === 1">
							<view data-loader="rectangle"></view>
						</view>
					</view>
					<view class="info">
						<view class="h3 ell">{{ item.title }}</view>
						<view class="desc ell">{{ item.nickname }}</view>
					</view>
					<view class="btnFlex flex">
						<view class="btnItem iconfont icon-yuyinguanbi"></view>
						<view class="btnItem iconfont icon-list" style="font-size: calc(37rpx * var(--fss));"></view>
					</view>
				</view>
			</movable-view>
			<movable-view class="touch_move" :x="2000" :y="0" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" />
		</movable-area>
		<view style="height: 20rpx;"></view>
	</scroll-view>
</template>

<script setup>
	import { ref, onMounted, defineProps, defineEmits, inject, computed, watch } from "vue";
	const app = inject('app');
	const emit = defineEmits(["dragSortChange"]);
	
	/* props父组件传参区域 */
	// 接受props
	const prop = defineProps({
		
		// 传入的列表
		list: {
			type: Array,
			default: [],
		},
		
		// 单个item的高度px
		height: {
			type: Number,
			default: 75
		},
		
	});
	
	/* 变量区域 */
	// 将当前列表写到组件里面去
	const currentList = ref([]);
	
	// 当前激活的item
	const active = ref(-1); 
	
	// 当前激活的item的原index
	const itemIndex = ref(0);
	
	// 距离顶部的距离
	const topY = ref(0);
	
	// 偏移量
	const deviationY = ref(0);
	
	
	/* 方法区域 */
	function isPreventDefault(e){
		if(active.value !== -1){
			e.stopPropagation();
			e.preventDefault();
		}
	}
	function onUpdateCurrentList(list) {
		currentList.value = list.map((item, index) => {
			return {
				...item,
				sort: index,
				index,
				y: index * prop.height,
				animation: true
			}
		});
	}
	function touchstart(e) {
		// 计算y轴点击位置
		const query = uni.createSelectorQuery().in(this);
		query.select('#drag').boundingClientRect();
		query.exec((res) => {
			topY.value = res[0].top;
			let touchY = e.touches[0].clientY - res[0].top;
			deviationY.value = touchY % prop.height;
			for (const key in currentList.value) {
				if ((currentList.value[key].index * prop.height < touchY) && ((currentList.value[key].index + 1) * prop.height > touchY)) {
					active.value = Number(key);
					itemIndex.value = currentList.value[key].index;
					break
				}
			}
		});
		//#ifdef APP-PLUS
		app.util.feedbackGeneratorState();
		//#endif
	}
	function touchmove(e) {
		if (active.value < 0) return
		let touchY = (e.touches[0].clientY - topY.value) - deviationY.value;
		currentList.value[active.value].y = touchY;
		for (const key in currentList.value) {
			// 跳过当前操作的item
			if (currentList.value[key].index !== currentList.value[active.value].index) {
				if (currentList.value[key].index > currentList.value[active.value].index) {
					if (touchY > currentList.value[key].index * prop.height - prop.height / 2) {
						currentList.value[active.value].index = currentList.value[key].index;
						currentList.value[key].index = currentList.value[key].index - 1;
						currentList.value[key].y = currentList.value[key].index * prop.height;
						break
					}
				} else {
					if (touchY < currentList.value[key].index * prop.height + prop.height / 2) {
						currentList.value[active.value].index = currentList.value[key].index;
						currentList.value[key].index = currentList.value[key].index + 1;
						currentList.value[key].y = currentList.value[key].index * prop.height;
						break
					}
				}
			}
		}
	}
	function touchend(e) {
		currentList.value[active.value].animation = true
		currentList.value[active.value].y = currentList.value[active.value].index * prop.height;
		if ((itemIndex.value !== currentList.value[active.value].index) && (active.value > -1)) {
			// 一旦位置发生改变
			let list = JSON.parse(JSON.stringify(currentList.value));
			list.sort((a, b) => {
				return a.y > b.y ? 1 : -1;
			});

			let e = {
				list: list,
				// 操作值
				data: (() => {
					let data = {
						...currentList.value[active.value]
					}
					return data
				})(),
				// 插队的位置前面的值
				frontData: (() => {
					for (const iterator of currentList.value) {
						if (currentList.value[active.value].index - 1 === iterator.index) {
							let data = {
								...iterator
							}
							return data
						}
					}
				})()
			}
			emit('dragSortChange', e);
		}
		active.value = -1
	}
	
	
	// 计算当前list长度
	const currentListLength = computed(() => {
		return currentList.value.length * prop.height;
	});
	
	// 监听列表变化则通知父级组件
	watch(prop.list, (newValue, oldValue) => {
		onUpdateCurrentList(newValue);
	}, { immediate: true,deep: true });
</script>

<style lang="scss" scoped>
	.group{
		margin-top: 25rpx;
		height: 65vh;
		@mixin flexLayout($align: center, $justify: center, $direction: row, $wrap: nowrap) {
			@if $align=='start' {
				$align: flex-start
			}
			@if $align=='end' {
				$align: flex-end
			}
			@if $justify=='start' {
				$justify: flex-start
			}
			@if $justify=='end' {
				$justify: flex-end
			}
			display: flex;
			align-items: $align;
			justify-content: $justify;
			flex-direction: $direction;
			flex-wrap: $wrap;
		}
		// 文字溢出隐藏... (rows - 显示行数)
		@mixin overflowEllipsis($rows: 1) {
			white-space: pre-wrap;
			overflow: hidden;
			text-overflow: ellipsis;
			display: -webkit-box;
			-webkit-box-orient: vertical;
			-webkit-line-clamp: $rows;
		}
		.drag-sort {
			width: 100%;
			&-item {
				position: absolute !important;
				display: flex;
				align-items: center;
				padding: 0;
				margin: 0;
				box-sizing: border-box;
				width: 100%;
				overflow: hidden;
				.item{
					flex: 1;
					width: 0;
					height: 100%;
					padding: 0 $padding;
					flex-direction: row;
					align-items: center;
					.imageView{
						flex-direction: row;
						position: relative;
						border-radius: 12rpx;
						width: 75px * 0.76;
						height: 75px * 0.76;
						&:after{
							content: "";
							position: absolute;
							top: 0;
							left: 0;
							right: 0;
							bottom: 0;
							border-radius: 12rpx;
							background: rgba(0,0,0,0.3);
							z-index: 1;
						}
						.image{
							width: 100%;
							height: 100%;
							border-radius: 12rpx;
						}
						.flex{
							z-index: 2;
							position: absolute;
							top: 50%;
							left: 50%;
							transform: translate(-50%, -50%);
							height: 55rpx;
							width: 55rpx;
							flex-direction: row;
							align-items: center;
							justify-content: center;
							[data-loader=rectangle] {
								position: relative;
								height: 12rpx;
								width: 4rpx;
								animation: rectangle infinite 1s ease-in-out -.2s;
								background-color: rgba(255,255,255,1);
								border-radius: 60rpx;
								&:before {
									left: -12rpx;
									animation: rectangle infinite 1s ease-in-out -.4s;
									border-radius: 60rpx;
								}
								&:after {
									right: -12rpx;
									animation: rectangle infinite 1s ease-in-out;
								}
								&:after,
								&:before {
									position: absolute;
									width: 4rpx;
									height: 12rpx;
									content: '';
									background-color: rgba(255,255,255,1);
									border-radius: 60rpx;
								}
							}
							@keyframes rectangle {
								0%,100%,80% {height: 12rpx;box-shadow: 0 0 rgba(255,255,255,1);}
								40% {height: 20rpx;box-shadow: 0 -12rpx rgba(255,255,255,1);}
							}
						}
					}
					.info{
						flex: 1;
						width: 0;
						margin: 0 25rpx;
						.h3{
							font-size: calc(27rpx * var(--fss));
							line-height: 1.2;
							color: rgba(255,255,255,0.95);
						}
						.desc{
							font-size: calc(24rpx * var(--fss));
							line-height: 1.2;
							color: rgba(255,255,255,0.6);
							margin-top: 10rpx;
						}
					}
					.btnFlex{
						flex-direction: row;
						align-items: center;
						margin-right: -5rpx;
						.btnItem{
							font-size: calc(27rpx * var(--fss));
							color: rgba(255,255,255,0.45);
							margin-left: 20rpx;
							width: 40rpx;
							text-align: center;
							line-height: 70rpx;
						}
					}
				}
			}
		}
		.item_after {
			position: relative;
			&:before {
				content: " ";
				position: absolute;
				left: 0;
				top: 0;
				right: 0;
				height: 1px;
				/*border-top: 1px solid #F6F6F6;*/
				color: #EEE;
				transform-origin: 0 0;
				transform: scaleY(0.5);
			}
		}
		.touch_move {
			height: 100%;
			width: 60rpx;
			left: inherit;
			right: 16rpx;
			transform: none!important;
		}
		.item_active {
			box-shadow: 0 0 40rpx #000;
			z-index: 99;
		}
	}
</style>